home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-11-03 | 3.5 KB | 109 lines | [TEXT/GEOL] |
- Item forwarded by A33 to A34
-
- Item 8064993 2-Nov-89 18:18
-
- From: ROSENSTEIN1 Rosenstein, Larry
-
- To: MACAPP.TECH$ MacApp Technical
-
- Sub: re PerformCommand problems
-
- Curtis,
-
- In general, the Commit method must be called before the DoIt method of the next
- command. This is because the Commit method might change the internal data
- structures, and the DoIt method might look at those data structures.
-
- If you allow the old command to exist while the new command's DoIt is called,
- then the application will have to be written to support 2 levels of undo (for
- the short time when these commands both exist).
-
- You could check whether the last command needs to be committed both before and
- after the call to DoIt, but that seems like a awkward way to handle this case.
-
- It seems to me that after the TrackMouse is done, the command object should
- know whether it is undoable or not. By the time the mouse button is released,
- you should know if the command is undoable or not. (Ignoring out-of-memory
- conditions.) You can always call a method before TrackMouse exits, which will
- set fCanUndo correctly.
-
- Exceptions change this. The command may normally be undoable, but because of a
- lack of memory, or some other exception, it won't be undoable in this case.
- (For example, you can't allocate the memory to save the current selection.)
-
- You could change the value of fCanUndo in the DoIt method, provided
- fCausesChange is TRUE. Then, the last command would be committed, the new
- command would be done, and the Undo menu item would be grayed out.
-
- The big disadvantage of this is that the user didn't have any say on whether to
- go ahead with the command when it wasn't undoable. I think the best solution
- to this is to ensure that the DoIt method can't fail. This means allocating
- any memory it needs to undo before the DoIt method.
-
- Larry Rosenstein
-
-
-
-
-
-
-
- Ideally I would like to be able to have the DoIt method set the state of
- fCanUndo to the correct value depending on whether the actions of DoIt are
- undoable or not.
-
- Presently this decision cannot be in DoIt because TApplication.Perform Command
- executes in the order:
-
- saveCmd := command.fCausesChange | command.fCanUndo;
-
- IF saveCmd THEN
- CommitLastCommand;
-
- ......
-
- command.DoIt;
-
- IF saveCmd THEN
- BEGIN
- gLastCommand := command;
- command.fCmdDone := TRUE;
- END;
-
- Hence if fCanUndo is False then even if Doit sets fCanUndo to TRUE:
- gLastCommand is not Set
- command.fCmdDone is not set to TRUE
- CommitLastCommand is not called
-
- because the value of saveCommand is set before DoIt.
-
- Why could saveCommand not be computed after DoIt and CommitLastCommand be
- deferred? Perhaps there is some concern that DoIt relies on the
- previousCommand having been committed? I do not know whether this is a more
- valid generalization than assuming that DoIt will not change fCanUndo.
-
- Is there something wrong with changing fCanUndo in DoIt? (conceptually at
- least, it is wrong now because it does not work)
-
- At the least PerformCommand could check
-
- { CommitLastCommand would have set gLastCommand to NIL if already executed }
- IF gLastCommand <> NIL and command.fCanUndo THEN
- BEGIN
- CommitLastCommand;
- saveCommand := TRUE;
- END;
-
- right after DoIt, this would have the effect of enabling changes in fCanUndo
- while still ensuring that if the last command's state should be committed
- before DoIt it would be. I am not sure that this is even necessary.
-
- Anyone have any thoughts on this?
-
- - Curtis
-
-
-
-
-
-